"""
created@2019/11/4
"""
from flask_restful import Resource, reqparse
from datetime import datetime
from utils.resp import Resp
from utils.check import check_group_message
from utils.query import task_info_after_execute, task_info_before_execute
from models.silo import Group, Message, GroupMessage, Task, TaskHasGroupMessage
from extensions import db
from daemon.task import wx_app_forward
from sqlalchemy import desc


class TaskListApi(Resource):
    
    def get(self):
        """获取任务列表"""
        
        tasks = Task.query.order_by(desc(Task.created_at)).all()
        """
        SELECT silo.tasks.id AS silo_tasks_id, silo.tasks.created_at AS silo_tasks_created_at, silo.tasks.updated_at AS silo_tasks_updated_at, silo.tasks.title AS silo_tasks_title, silo.tasks.description AS silo_tasks_description, silo.tasks.send_type AS silo_tasks_send_type, silo.tasks.executed_at AS silo_tasks_executed_at 
        FROM silo.tasks ORDER BY silo.tasks.created_at DESC
        """
        data = []
        for task in tasks:
            task_data = dict()
            task_data["task_id"] = task.id
            task_data["title"] = task.title
            task_data["description"] = task.description
            task_data["executed_at"] = str(task.executed_at) if task.executed_at else ''
            task_data["created_at"] = str(task.created_at)
            task_data["updated_at"]  = str(task.updated_at)
            data.append(task_data)
        return Resp.ok(data=data)
    
    def post(self):
        """创建任务"""
        
        parser = reqparse.RequestParser() 
        parser.add_argument('title', type=str, required=True, default='')
        parser.add_argument('description', type=str, required=True, default='')
        parser.add_argument('group_messages', type=list, required=True, location='json', default=[])
        args = parser.parse_args()
        if not args.group_messages:
            return Resp.bad_request(errmsg='group_messages不能为空', code=400)
        # 如果不是任意数据检查都通过
        if not all(map(lambda item:check_group_message(item), args.group_messages)):
            return Resp.bad_request(errmsg='group_messages数据有误', code=400)

        # 单个公众号对推送对象的推送消息
        group_messages = []
        for group_msg in args.group_messages:
            # 查询group针对于哪几个公众号
            message = Message.query.get(group_msg['msg_id'])
            group = Group.query.get(group_msg['group_id'])
            if not message:
                return Resp.not_found(errmsg='不存在的msg_id: {}'.format(group_msg['msg_id']))
            if not group:
                return Resp.not_found(errmsg='不存在的group_id: {}'.format(group_msg['group_id']))

            # 当前消息不为文本消息
            if message.msg_type != 'text':
                if group.parent_id == 0 and group.wx_app_id == 0:
                    # 父组
                    return Resp.bad_request(errmsg='不能为非文本消息配置适用于多个公众号的推送对象', code=400)
                if message.wx_app_id != group.wx_app_id:
                    return Resp.bad_request(errmsg='消息与推送对象的公众号不适配')
                # 单个公众号的group ==> 无父组且无子组
                group_message = GroupMessage(
                    wx_app_id=group.wx_app_id,
                    msg_id=message.id,
                    group_id=group.id
                )
                group_messages.append(group_message)
            # 当前消息为文本消息
            else:
                # 单个公众号的group
                # 子组   或者  没有子组的指向特定公众号的group
                if group.parent_id != 0 or (group.parent_id == 0 and group.wx_app_id != 0):
                    group_message = GroupMessage(
                        wx_app_id=group.wx_app_id,
                        msg_id=message.id,
                        group_id=group.id
                    )
                    group_messages.append(group_message)
                # 多个公众号的group
                else: 
                    parent_group = group
                    subgroups = Group.query.filter(Group.parent_id==parent_group.id)
                    for subgroup in subgroups:
                        group_message = GroupMessage(
                            wx_app_id=subgroup.wx_app_id,
                            msg_id=message.id,
                            group_id=subgroup.id
                        )
                        group_messages.append(group_message)
        # 创建任务
        task = Task(title=args.title, description=args.description)
        db.session.add_all(group_messages+[task])
        db.session.flush()
        # 需要存储的记录
        task_has_group_msgs = []
        for group_message in group_messages:
            task_has_group_msg = TaskHasGroupMessage(
                task_id=task.id,
                group_msg_id=group_message.id
            )
            task_has_group_msgs.append(task_has_group_msg)
        db.session.add_all(task_has_group_msgs)
        executed_at = str(task.executed_at) if task.executed_at else ''
        # 需要返回的数据
        data = dict()
        data.update(
            title=task.title,
            task_id=task.id,
            description=task.description,
            executed_at=executed_at,
            created_at=str(task.created_at),
            updated_at=str(task.updated_at)
        )
        db.session.commit()
        return Resp.ok(data=data)
    
    
class TaskExecuteApi(Resource):
    
    def post(self):
        """执行任务"""

        parser = reqparse.RequestParser()
        parser.add_argument('task_id', type=int, required=True)
        parser.add_argument('test_mode', type=bool, default=False)
        args = parser.parse_args()
        task = Task.query.get(args.task_id)
        """
        SELECT silo.tasks.id AS silo_tasks_id, silo.tasks.created_at AS silo_tasks_created_at, silo.tasks.updated_at AS silo_tasks_updated_at, silo.tasks.title AS silo_tasks_title, silo.tasks.description AS silo_tasks_description, silo.tasks.send_type AS silo_tasks_send_type, silo.tasks.executed_at AS silo_tasks_executed_at 
        FROM silo.tasks 
        WHERE silo.tasks.id = %(param_1)s
        """
        if not task:
            return Resp.not_found(errmsg='您要执行的任务不存在')
        if task.executed_at:
            return Resp.ok(errmsg='请不要重复执行任务，如有必要请重新创建任务。')
        res = db.session.query(GroupMessage.msg_id, TaskHasGroupMessage.id, Group.query_sql)\
            .join(TaskHasGroupMessage, TaskHasGroupMessage.group_msg_id == GroupMessage.id)\
            .join(Group, Group.id == GroupMessage.group_id)\
            .filter(TaskHasGroupMessage.task_id == task.id).all()
        """
        SELECT silo.group_messages.msg_id AS silo_group_messages_msg_id, silo.task_has_group_messages.id AS silo_task_has_group_messages_id, silo.`groups`.query_sql AS silo_groups_query_sql 
        FROM silo.group_messages INNER JOIN silo.task_has_group_messages ON silo.task_has_group_messages.group_msg_id = silo.group_messages.id INNER JOIN silo.`groups` ON silo.`groups`.id = silo.group_messages.group_id 
        WHERE silo.task_has_group_messages.task_id = %(task_id_1)s
        """


        # 将多个推送分发
        for msg_id, task_has_group_msg_id, query_sql in res:
            wx_app_forward.delay(msg_id, task_has_group_msg_id, query_sql, args.test_mode)
        now = datetime.now().replace(microsecond=0)
        task.executed_at = now
        db.session.commit()
        data = {"task_id": task.id, "executed_at": str(now)}
        return Resp.ok(data=data, errmsg='您的任务已经开始执行，请耐心等待反馈')
    
    
class TaskApi(Resource):

    def get(self, task_id):
        """获取单个任务信息"""

        task = Task.query.get(task_id)
        if not task:
            return Resp.bad_request(errmsg='任务不存在')
        if task.executed_at:
            group_messages = task_info_after_execute(task_id)
        else:
            group_messages = task_info_before_execute(task_id)
        
        data = {
            'task_id': task_id,
            "group_messages": group_messages
        }
        return Resp.ok(data=data)

